#include "animation.h"
#include "defs.h"
#include "draw.h"
#include "font.h"
#include "init.h"
#include "input.h"
#include "main.h"
#include "map.h"
#include "sounds.h"
#include "menu.h"
#include "player.h"
#include "monster.h"
#include "structs.h"
#include "plateformes.h"

  void loadMap(char *name)
 {
    int x, y;
    FILE *fp;

    fp = fopen(name, "rb");


    if (fp == NULL)
    {
        printf("Failed to open map %s\n", name);
        exit(1);
    }


    map.maxX = map.maxY = 0;

    for (y = 0; y < MAX_MAP_Y; y++)
    {
        for (x = 0; x < MAX_MAP_X; x++)
        {

            fscanf(fp, "%d", &map.tile[y][x]);


            if (map.tile[y][x] > 0)
            {
                if (x > map.maxX)
                {
                    map.maxX = x;
                }

                if (y > map.maxY)
                {
                    map.maxY = y;
                }
            }
        }
    }


    map.maxX = (map.maxX + 1) * TILE_SIZE;
    map.maxY = (map.maxY + 1) * TILE_SIZE;



    map.startX = map.startY = 0;



    fclose(fp);

  }




  void drawMap(void)
 {
    int x, y, mapX, x1, x2, mapY, y1, y2, xsource, ysource, a;
    const SDL_VideoInfo* myPointer = SDL_GetVideoInfo();

    mapX = map.startX / TILE_SIZE;

    x1 = (map.startX % TILE_SIZE) * -1;

    x2 = x1 + myPointer->current_w + (x1 == 0 ? 0 : TILE_SIZE);


    mapY = map.startY / TILE_SIZE;
    y1 = (map.startY % TILE_SIZE) * -1;
    y2 = y1 + myPointer->current_h + (y1 == 0 ? 0 : TILE_SIZE);

    if(map.mapTimer <= 0)
    {
        if(map.tileSetNumber == 0)
        {
            map.tileSetNumber = 1;
            map.mapTimer = TIME_BETWEEN_2_FRAMES*3;
        }
        else
        {
            map.tileSetNumber = 0;
            map.mapTimer = TIME_BETWEEN_2_FRAMES*3;
        }

    }

    else
        map.mapTimer--;



    for (y = y1; y < y2; y += TILE_SIZE)
    {

        mapX = map.startX / TILE_SIZE;


        for (x = x1; x < x2; x += TILE_SIZE)
        {
            if (map.tile[mapY][mapX] != 0)
            {

                if (map.tile[mapY][mapX] == 22)
                {
                    initializeMonster(mapX * TILE_SIZE, mapY * TILE_SIZE);

                    map.tile[mapY][mapX] = 0;
                }
                else if (map.tile[mapY][mapX] >= TILE_PLATEFORME_DEBUT
                         && map.tile[mapY][mapX] <= TILE_PLATEFORME_FIN)
                {
                    initPlateforme(mapX * TILE_SIZE, mapY * TILE_SIZE, map.tile[mapY][mapX] - TILE_PLATEFORME_DEBUT +1);

                    map.tile[mapY][mapX] = 0;
                }
            }

            a = map.tile[mapY][mapX];


            ysource = a / 10 * TILE_SIZE;



            xsource = a % 10 * TILE_SIZE;

                     if(map.tileSetNumber == 0)
                drawTile(map.tileSet, x, y, xsource, ysource);
            else
                drawTile(map.tileSetB, x, y, xsource, ysource);
            mapX++;
        }

        mapY++;
    }
  }

    void mapCollision(GameObject *entity)
 {

    int i, x1, x2, y1, y2;


    entity->onGround = 0;



    if(entity->h > TILE_SIZE)
        i = TILE_SIZE;
    else
        i = entity->h;



    for (;;)
    {


        x1 = (entity->x + entity->dirX) / TILE_SIZE;
        x2 = (entity->x + entity->dirX + entity->w/1.25) / TILE_SIZE;


        y1 = (entity->y) / TILE_SIZE;
        y2 = (entity->y + i - 1) / TILE_SIZE;


        if (x1 >= 0 && x2 < MAX_MAP_X && y1 >= 0 && y2 < MAX_MAP_Y)
        {
            {
                if (entity->dirX > 0)
            {
                if (map.tile[y1][x2] == 21)
                {
                    getItem();
                    map.tile[y1][x2] = 0;
                }
               else if (map.tile[y2][x2] == 21)
                {
                    getItem();
                    map.tile[y2][x2] = 0;
                }
                             //Test de la tile checkpoint
                if (map.tile[y1][x2] == 20)
                {
                    //On active le booléen checkpoint
                    entity->checkpointActif = 1;

                    //On enregistre les coordonnées
                    entity->respawnX = x2 * TILE_SIZE;
                    entity->respawnY= (y1 * TILE_SIZE) - entity->h;

                    //On change la tile
                    map.tile[y1][x2] = 32;
                }
                else if (map.tile[y2][x2] == 20)
                {
                    //On active le booléen checkpoint
                    entity->checkpointActif = 1;

                    //On enregistre les coordonnées
                    entity->respawnX = x2 * TILE_SIZE;
                    entity->respawnY= (y2 * TILE_SIZE) - entity->h;

                    //On change la tile
                    map.tile[y2][x2] = 32;
                }
                switch (map.tile[y1][x2])
                {
                    case 24:
                    getKey1();
                    map.tile[y1][x2]=0;
                    break;
                    case 25:
                    getKey2();
                    map.tile[y1][x2]=0;
                    break;
                    case 26:
                    getKey3();
                    map.tile[y1][x2]=0;
                    break;
                    case 27:
                    map.tile[y1][x2]=0;
                    jeu.onMenu = 1;
                    jeu.menuType = INSTRUC;
                    input.enter = 0;
                    break;
                    case 28:
                    entity->timerMort=1;
                    break;
                    case 29:
                    entity->timerMort=1;
                    break;
                    case 30:
                    entity->timerMort=1;
                    break;
                    case 31:
                    entity->timerMort=1;
                    break;
                   }
                switch (map.tile[y2][x2])
                {
                    case 24:
                    getKey1();
                    map.tile[y2][x2]=0;
                    break;
                    case 25:
                    getKey2();
                    map.tile[y2][x2]=0;
                    break;
                    case 26:
                    getKey3();
                    map.tile[y2][x2]=0;
                    break;
                    case 27:
                    jeu.onMenu = 1;
                    jeu.menuType = INSTRUC;
                    input.enter = 0;
                    map.tile[y2][x2]=0;
                    break;
                    case 28:
                    entity->timerMort=1;
                    break;
                    case 29:
                    entity->timerMort=1;
                    break;
                    case 30:
                    entity->timerMort=1;
                    break;
                    case 31:
                    entity->timerMort=1;
                    break;
                   }
                if ((map.tile[y2][x2]== 23) && (jeu.key1 == 1) && (jeu.key2 == 1) && (jeu.key3 == 1))
                {
                       {
                     jeu.level++;
                       if(jeu.level > LEVEL_MAX)
                        {
                         jeu.level = LEVEL_MAX;
                        entity->x = TILE_SIZE - entity->w-1;
                          }
                    else
                  {
                      entity->checkpointActif = 0;
                changeLevel();
               initializePlayer();
             }
         }
                }

                if ((map.tile[y1][x2] > BLANK_TILE || map.tile[y2][x2] > BLANK_TILE) && (jeu.level!=3))
                {
                    entity->x = x2 * TILE_SIZE;

                    entity->x -= entity->w/1.25;

                    entity->dirX = 0;


                }
                else if ((map.tile[y1][x2] > BLANK_TILE || map.tile[y2][x2] > BLANK_TILE) && (jeu.level==3))
                    entity->timerMort=1;
            }

            else if (entity->dirX < 0)
            {

                if (map.tile[y1][x1] == 21)
                {

                    getItem();

                    map.tile[y1][x1] = 0;
                }
                else if(map.tile[y2][x1] == 21)
                {
                    getItem();
                    map.tile[y2][x1] = 0;
                }
                if (map.tile[y1][x1]==20)
                {
                    entity->checkpointActif = 1;
                    entity->respawnX=x1*TILE_SIZE;
                    entity->respawnY=(y1*TILE_SIZE) - entity->h;
                    map.tile[y1][x1] =32;

                }
                else if (map.tile[y2][x1]==20)
                 {
                     entity->checkpointActif =1;
                     entity->respawnX = x1*TILE_SIZE;
                     entity->respawnY= (y2*TILE_SIZE)-entity->h;
                     map.tile[y2][x1] =32;
                    }
                switch (map.tile[y1][x1])
                {
                    case 24:
                    getKey1();
                    map.tile[y1][x1]=0;
                    break;
                    case 25:
                    getKey2();
                    map.tile[y1][x1]=0;
                    break;
                    case 26:
                    getKey3();
                    map.tile[y1][x1]=0;
                    break;
                    case 27:
                    jeu.onMenu = 1;
                    jeu.menuType = INSTRUC;
                    input.enter = 0;
                    map.tile[y1][x1]=0;
                    break;
                    case 28:
                    entity->timerMort=1;
                    break;
                    case 29:
                    entity->timerMort=1;
                    break;
                    case 30:
                    entity->timerMort=1;
                    break;
                    case 31:
                    entity->timerMort=1;
                    break;
                   }
                switch (map.tile[y2][x1])
                {
                    case 24:
                    getKey1();
                    map.tile[y2][x1]=0;
                    break;
                    case 25:
                    getKey2();
                    map.tile[y2][x1]=0;
                    break;
                    case 26:
                    getKey3();
                    map.tile[y2][x1]=0;
                    break;
                    case 27:
                    jeu.onMenu = 1;
                    jeu.menuType = INSTRUC;
                    input.enter = 0;
                    map.tile[y2][x1]=0;
                    break;
                    case 28:
                    entity->timerMort=1;
                    break;
                    case 29:
                    entity->timerMort=1;
                    break;
                    case 30:
                    entity->timerMort=1;
                    break;
                    case 31:
                    entity->timerMort=1;
                    break;
                   }

                if ((map.tile[y1][x1] > BLANK_TILE || map.tile[y2][x1] > BLANK_TILE) && (jeu.level!=3))
                {

                    entity->x = (x1 + 1) * TILE_SIZE;

                    entity->dirX = 0;
                }
                else if ((map.tile[y1][x1] > BLANK_TILE || map.tile[y2][x1] > BLANK_TILE) && (jeu.level==3))
                    entity->timerMort=1;
            }
        }
        }
        if (i == entity->h)
        {
            break;
        }

        i += TILE_SIZE;

        if (i > entity->h)
        {
            i = entity->h;
        }
    }

    if(entity->w > TILE_SIZE)
        i = TILE_SIZE;
    else
        i = entity->w;


    for (;;)
    {
        x1 = (entity->x) / TILE_SIZE;
        x2 = (entity->x + i/1.25) / TILE_SIZE;

        y1 = (entity->y + entity->dirY) / TILE_SIZE;
        y2 = (entity->y + entity->dirY + entity->h) / TILE_SIZE;

        if (x1 >= 0 && x2 < MAX_MAP_X && y1 >= 0 && y2 < MAX_MAP_Y)
        {
           {       if (entity->dirY > 0)
            {

                if (map.tile[y2][x1] == 21)
                {
                    getItem();
                    map.tile[y2][x1] = 0;
                }
                else if(map.tile[y2][x2] == 21)
                {
                    getItem();
                    map.tile[y2][x2] = 0;
                }
                   //Test de la tile checkpoint
                if (map.tile[y2][x1] == 20)
                {
                    //On active le booléen checkpoint
                    entity->checkpointActif = 1;

                    //On enregistre les coordonnées
                    entity->respawnX = x1 * TILE_SIZE;
                    entity->respawnY= (y2 * TILE_SIZE) - entity->h;

                    //On change la tile
                    map.tile[y2][x1] = 32;
                }
                else if (map.tile[y2][x2] == 20)
                {
                    //On active le booléen checkpoint
                    entity->checkpointActif = 1;

                    //On enregistre les coordonnées
                    entity->respawnX = x2 * TILE_SIZE;
                    entity->respawnY= (y2 * TILE_SIZE) - entity->h;

                    //On change la tile
                    map.tile[y2][x2] = 32;
                }

                switch (map.tile[y2][x1])
                {
                    case 24:
                    getKey1();
                    map.tile[y2][x1]=0;
                    break;
                    case 25:
                    getKey2();
                    map.tile[y2][x1]=0;
                    break;
                    case 26:
                    getKey3();
                    map.tile[y2][x1]=0;
                    break;
                    case 27:
                    map.tile[y2][x1]=0;
                    jeu.onMenu = 1;
                    jeu.menuType = INSTRUC;
                    input.enter = 0;
                    break;
                    case 28:
                    entity->timerMort=1;
                    break;
                    case 29:
                    entity->timerMort=1;
                    break;
                    case 30:
                    entity->timerMort=1;
                    break;
                    case 31:
                    entity->timerMort=1;
                    break;
                   }
                switch (map.tile[y2][x2])
                {
                    case 24:
                    getKey1();
                    map.tile[y2][x2]=0;
                    break;
                    case 25:
                    getKey2();
                    map.tile[y2][x2]=0;
                    break;
                    case 26:
                    getKey3();
                    map.tile[y2][x2]=0;
                    break;
                    case 27:
                    jeu.onMenu = 1;
                    jeu.menuType = INSTRUC;
                    input.enter = 0;
                    map.tile[y2][x2]=0;
                    break;
                    case 28:
                    entity->timerMort=1;
                    break;
                    case 29:
                    entity->timerMort=1;
                    break;
                    case 30:
                    entity->timerMort=1;
                    break;
                    case 31:
                    entity->timerMort=1;
                    break;
                   }

                if ((map.tile[y2][x1] > BLANK_TILE || map.tile[y2][x2] > BLANK_TILE) && (jeu.level!=3))
                {
                    entity->y = y2 * TILE_SIZE;
                    entity->y -= entity->h;

                    entity->dirY = 0;
                    entity->onGround = 1;
                }
                             else if ((map.tile[y2][x1] > BLANK_TILE || map.tile[y2][x2] > BLANK_TILE) && (jeu.level==3))
                    entity->timerMort=1;

            }


            else if (entity->dirY < 0)
            {

                if (map.tile[y1][x1] == 21)
                {
                    getItem();
                    map.tile[y1][x1] = 0;
                }
                else if (map.tile[y1][x2] == 21)
                {

                    getItem();

                    map.tile[y1][x2] = 0;
                }
                     if (map.tile[y1][x1] == 20)
                {
                    //On active le booléen checkpoint
                    entity->checkpointActif = 1;

                    //On enregistre les coordonnées
                    entity->respawnX = x1 * TILE_SIZE;
                    entity->respawnY= (y1 * TILE_SIZE) - entity->h;

                    //On change la tile
                    map.tile[y1][x1] = 32;
                }
                else if (map.tile[y1][x2] == 20)
                {
                    //On active le booléen checkpoint
                    entity->checkpointActif = 1;

                    //On enregistre les coordonnées
                    entity->respawnX = x2 * TILE_SIZE;
                    entity->respawnY= (y1 * TILE_SIZE) - entity->h;

                    //On change la tile
                    map.tile[y1][x2] = 32;
                }
                switch (map.tile[y1][x1])
                {
                    case 24:
                    getKey1();
                    map.tile[y1][x1]=0;
                    break;
                    case 25:
                    getKey2();
                    map.tile[y1][x1]=0;
                    break;
                    case 26:
                    getKey3();
                    map.tile[y1][x1]=0;
                    break;
                    case 27:
                    jeu.onMenu = 1;
                    jeu.menuType = INSTRUC;
                    input.enter = 0;
                    map.tile[y1][x1]=0;
                    break;
                    case 28:
                    entity->timerMort=1;
                    break;
                    case 29:
                    entity->timerMort=1;
                    break;
                    case 30:
                    entity->timerMort=1;
                    break;
                    case 31:
                    entity->timerMort=1;
                    break;

                   }
                switch (map.tile[y1][x2])
                {
                    case 24:
                    getKey1();
                    map.tile[y1][x2]=0;
                    break;
                    case 25:
                    getKey2();
                    map.tile[y1][x2]=0;
                    break;
                    case 26:
                    getKey3();
                    map.tile[y1][x2]=0;
                    break;
                    case 27:
                    jeu.onMenu = 1;
                    jeu.menuType = INSTRUC;
                    input.enter = 0;
                    map.tile[y1][x2]=0;
                    break;
                    case 28:
                    entity->timerMort=1;
                    break;
                    case 29:
                    entity->timerMort=1;
                    break;
                    case 30:
                    entity->timerMort=1;
                    break;
                    case 31:
                    entity->timerMort=1;
                    break;
                   }

                if ((map.tile[y1][x1] > BLANK_TILE || map.tile[y1][x2] > BLANK_TILE) && (jeu.level!=3))
                {

                    entity->y = (y1 + 1) * TILE_SIZE;

                    entity->dirY = 0;

                }
                        else if ((map.tile[y1][x1] > BLANK_TILE || map.tile[y1][x2] > BLANK_TILE) && (jeu.level==3))
                entity->timerMort=1;

            }
           }
        }

        if (i == entity->w)
        {
            break;
        }

        i += TILE_SIZE;

        if (i > entity->w)
        {
            i = entity->w;
        }
    }

    entity->x += entity->dirX;
    entity->y += entity->dirY;


    if (entity->x < 0)
    {
        entity->x = 0;
    }

    if (entity->y > map.maxY)
    {
        entity->timerMort = 60;
    }

    /* Test de collision avec la plateforme mobile */
int j;

if (jeu.nombrePlateformes > 0)
{
for ( j=1 ; j <= jeu.nombrePlateformes ; j++ )
{
    if ( entity->x + entity->w >= plateforme[j].x
        && entity->x <= plateforme[j].x + plateforme[j].w
        && entity->y + entity->h >= plateforme[j].y
        && entity->y + entity->h < plateforme[j].y + 32 )
        {

            entity->y = plateforme[j].y - entity->h;
            entity->dirY = 0;
            entity->onGround = 1;
            plateforme[j].player_dessus = 1;
        }
        else
            plateforme[j].player_dessus = 0;
    }
}
}
 void changeLevel(void)
{

    char file[200];
    jeu.key1=0;
    jeu.key2=0;
    jeu.key3=0;
       if (jeu.level==1)
     loadSong("music/mainmusic.MP3");
     if(jeu.level==2)
        loadSong("music/final.MP3");
        if (jeu.level==3)
            loadSong("music/essaie.MP3");

    sprintf(file, "map/map%d.txt", jeu.level );
    loadMap(file);

    if(map.background != NULL)
    {
        SDL_FreeSurface(map.background);
    }
    sprintf(file, "graphics/background%d.png", jeu.level );
    map.background = loadImage(file);

      if(map.tileSet != NULL)
    {
        SDL_FreeSurface(map.tileSet);
    }
    if(map.tileSetB != NULL)
    {
        SDL_FreeSurface(map.tileSetB);
    }
    sprintf(file, "graphics/tileset%d.png", jeu.level );
    map.tileSet = loadImage(file);
    sprintf(file, "graphics/tileset%dB.png", jeu.level );
    map.tileSetB = loadImage(file);

}

void monsterCollisionToMap(GameObject *entity)
{

    int i, x1, x2, y1, y2;

    entity->onGround = 0;

    if(entity->h > TILE_SIZE)
        i = TILE_SIZE;
    else
        i = entity->h;

    for (;;)
    {
        x1 = (entity->x + entity->dirX) / TILE_SIZE;
        x2 = (entity->x + entity->dirX + entity->w - 1) / TILE_SIZE;

        y1 = (entity->y) / TILE_SIZE;
        y2 = (entity->y + i - 1) / TILE_SIZE;

        if (x1 >= 0 && x2 < MAX_MAP_X && y1 >= 0 && y2 < MAX_MAP_Y)
        {

            if (entity->dirX > 0)
            {

                if (map.tile[y1][x2] > BLANK_TILE || map.tile[y2][x2] > BLANK_TILE)
                {
                    entity->x = x2 * TILE_SIZE;
                    entity->x -= entity->w + 1;
                    entity->dirX = 0;

                }

            }


            else if (entity->dirX < 0)
            {

                if (map.tile[y1][x1] > BLANK_TILE || map.tile[y2][x1] > BLANK_TILE)
                {
                    entity->x = (x1 + 1) * TILE_SIZE;
                    entity->dirX = 0;
                }

            }

        }


        if (i == entity->h)
        {
            break;
        }


        i += TILE_SIZE;

        if (i > entity->h)
        {
            i = entity->h;
        }
    }


    if(entity->w > TILE_SIZE)
        i = TILE_SIZE;
    else
        i = entity->w;


    for (;;)
    {
        x1 = (entity->x) / TILE_SIZE;
        x2 = (entity->x + i) / TILE_SIZE;

        y1 = (entity->y + entity->dirY) / TILE_SIZE;
        y2 = (entity->y + entity->dirY + entity->h) / TILE_SIZE;

        if (x1 >= 0 && x2 < MAX_MAP_X && y1 >= 0 && y2 < MAX_MAP_Y)
        {
            if (entity->dirY > 0)
            {



                if (map.tile[y2][x1] > BLANK_TILE || map.tile[y2][x2] > BLANK_TILE)
                {
                    entity->y = y2 * TILE_SIZE;
                    entity->y -= entity->h;
                    entity->dirY = 0;
                    entity->onGround = 1;
                }

            }

            else if (entity->dirY < 0)
            {



                if (map.tile[y1][x1] > BLANK_TILE || map.tile[y1][x2] > BLANK_TILE)
                {
                    entity->y = (y1 + 1) * TILE_SIZE;
                    entity->dirY = 0;
                }

            }
        }

        if (i == entity->w)
        {
            break;
        }

        i += TILE_SIZE;

        if (i > entity->w)
        {
            i = entity->w;
        }
    }


    entity->x += entity->dirX;
    entity->y += entity->dirY;

    if (entity->x < 0)
    {
        entity->x = 0;
    }

    else if (entity->x + entity->w >= map.maxX)
    {
        entity->x = map.maxX - entity->w - 1;
    }

    if (entity->y > map.maxY)
    {
        entity->timerMort = 60;
    }
}

void drawStartMenu(void)
{
 const SDL_VideoInfo* myPointer = SDL_GetVideoInfo();
    char text[200];

    //Le titre
    sprintf(text, "Captivity");
    drawString(text, 110, 0, font);


    if(jeu.choice != 0)
    {
        sprintf(text, "START");
        drawString(text, 273, 200, font);
    }
    if(jeu.choice != 1)
    {
        sprintf(text, "OPTIONS");
        drawString(text, 273, 280, font);
    }
    if (jeu.choice !=2)
    {
        sprintf(text, "QUIT");
        drawString(text,273,360,font);
    }

     //Si l'option est en surbrillance, on rajoute ">"
    if(jeu.choice == 0)
    {
        sprintf(text, "> START <");
        drawString(text, 250, 200, font);
    }
    else if(jeu.choice == 1)
    {
        sprintf(text, "> OPTIONS <");
        drawString(text, 250, 280, font);
    }
    else if (jeu.choice == 2)
    {
        sprintf(text,"> QUIT <");
        drawString(text,250,360,font);
    }

    sprintf(text, "Haw-X Games, 2014");
    drawString(text,myPointer->current_w - 400 , myPointer->current_h - 50, font);


}